#!/bin/sh
# qemu-debootstrap - setup qemu syscall emulation in a debootstrap chroot
# Copyright (C) 2010 Loïc Minier <lool@dooz.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# SOFTWARE IN THE PUBLIC INTEREST, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the author shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from the author.

set -e

log() {
    local format="$1"
    shift
    printf -- "$format\n" "$@" >&2
}

warn() {
    local format="$1"
    shift
    log "W: $format" "$@"
}

die() {
    local format="$1"
    shift
    log "E: $format" "$@"
    exit 1
}

run() {
    log "I: Running command: %s" "$*"
    "$@"
}

escape() {
    echo "$*" | sed "s/'/'\"'\"'/g; s/.*/'&'/"
}
unescape () {
    eval "echo" "$*"
}

system_arch="$(dpkg --print-architecture)"
deb_arch="$system_arch"

opts=""
args=""
suite=""
target=""
mirror=""
script=""
while [ $# -gt 0 ]; do
    case "$1" in
      --help)
        die "I'm just a debootstrap wrapper; please see debootstrap --help"
      ;;
      --arch|--arch=?*)
        if [ "$1" = "--arch" -a $# -ge 2 -a -n "$2" ]; then
            deb_arch="$2"
            shift 2
        elif [ "$1" != "${1#--arch=}" ]; then
            deb_arch="${1#--arch=}"
            shift
        else
            die "option %s requires an argument" "$1"
        fi
      ;;
      --include|--exclude|--components|--variant|--keyring|--unpack-tarball|--make-tarball|--second-stage-target|--extractor|--private-key|--certificate)
        if [ $# -ge 2 -a -n "$2" ]; then
            opts="$opts $(escape "$1") $(escape "$2")"
            shift 2
        else
            die "option %s requires an argument" "$1"
        fi
      ;;
      --*)
        opts="$opts $(escape "$1")"
        shift
      ;;
      *)
        if [ -z "$suite" ]; then stage="suite";
        elif [ -z "$target" ]; then stage="target";
        elif [ -z "$mirror" ]; then stage="mirror";
        elif [ -z "$script" ]; then stage="script";
        fi
        if [ -n "$1" ]; then
            eval $stage=\"\$1\"
            args="$args $(escape "$1")"
        else
            die "option %s may not be empty" "$stage"
        fi
        shift
      ;;
    esac
done

which debootstrap >/dev/null 2>/dev/null ||
  die "debootstrap isn't found in \$PATH, is debootstrap package installed?"

needs_qemu="yes"
if [ "$deb_arch" = "$system_arch" ]; then
    warn "Target architecture is the same as host architecture; disabling QEMU support"
    needs_qemu="no"
fi
# bi-arch; TODO test whether the running kernel is actually bi-arch capable
case "$system_arch-$deb_arch" in
  amd64-i386|arm-armel|armel-arm|arm-armhf|armhf-arm|armel-armhf|armhf-armel|i386-amd64|powerpc-ppc64|ppc64-powerpc|sparc-sparc64|sparc64-sparc|s390-s390x|s390x-s390)
    warn "Host architecture might allow running target architecture; disabling QEMU support"
    needs_qemu="no"
  ;;
esac

if [ "$needs_qemu" = no ]; then
    eval run debootstrap --arch "$deb_arch" $opts $args
    exit $?
fi

qemu_arch=""
case "$deb_arch" in
  alpha|arm|armeb|i386|m68k|mips|mipsel|mips64el|ppc64|sh4|sh4eb|sparc|sparc64|s390x)
    qemu_arch="$deb_arch"
  ;;
  amd64)
    qemu_arch="x86_64"
  ;;
  armel|armhf)
    qemu_arch="arm"
  ;;
  arm64)
    qemu_arch="aarch64"
  ;;
  lpia)
    qemu_arch="i386"
  ;;
  powerpc|powerpcspe)
    qemu_arch="ppc"
  ;;
  ppc64el)
    qemu_arch="ppc64le"
  ;;
  *)
    die "Sorry, I don't know how to support arch %s" "$arch"
  ;;
esac

if ! which "qemu-$qemu_arch-static" >/dev/null 2>&1; then
    die "Sorry, couldn't find binary %s" "qemu-$qemu_arch-static"
fi

eval run debootstrap --arch "$deb_arch" --foreign $opts $args
mkdir -p "$target/usr/bin"
cp $(which "qemu-$qemu_arch-static") "$target/usr/bin"
run chroot "$target" /debootstrap/debootstrap --second-stage

